package com.zhiche.lisa.bms.service.utils.common.identityCodeUtil.item;

import com.baomidou.mybatisplus.enums.SqlLike;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.zhiche.lisa.bms.dao.model.invoice.InvoiceApply;
import com.zhiche.lisa.bms.service.invoice.InvoiceApplyService;
import com.zhiche.lisa.bms.service.utils.common.identityCodeUtil.CodeSuper;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.CollectionUtils;

import java.util.Calendar;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;


/**
 * @Author: liuanshun
 * @Description:
 * @Date: Create in 10:41 2018/11/16
 */
@Deprecated
public class InvoiceApplyCode extends CodeSuper {

	private final Logger LOGGER = LoggerFactory.getLogger(InvoiceApplyCode.class);


	/**
	 * 开票申请Service，用于初始化时查询数据库
	 */
	private InvoiceApplyService invoiceApplyService;

	public InvoiceApplyCode(InvoiceApplyService invoiceApplyService) {
		this.invoiceApplyService = invoiceApplyService;
		this.mapper = new HashMap<>();
		this.setDateMapping();
		this.codeFactory = "AP[yyyy][MM][dd][incrementId]";
	}

	/**
	 * 指定获取4位数
	 *
	 * @return
	 */
	@Override
	protected String getNextIncrementId() {
		int newNum = codeId.incrementAndGet();
		//数字长度为4位，长度不够数字前面补0
		String newStrNum = String.format("%04d", newNum);
		return newStrNum;
	}

	private boolean checkNowDate() {
		Calendar instance = Calendar.getInstance();
		if (!String.valueOf(instance.get(Calendar.YEAR)).equals(mapper.get("yyyy"))) {
			return false;
		}
		if (!String.valueOf(instance.get(Calendar.MONTH)).equals(mapper.get("MM"))) {
			return false;
		}
		if (!String.valueOf(instance.get(Calendar.DAY_OF_MONTH)).equals(mapper.get("dd"))) {
			return false;
		}
		return true;
	}

	private void setDateMapping() {
		Calendar instance = Calendar.getInstance();
		mapper.put("yyyy", String.valueOf(instance.get(Calendar.YEAR)));
		mapper.put("MM", String.valueOf(instance.get(Calendar.MONTH)));
		mapper.put("dd", String.valueOf(instance.get(Calendar.DAY_OF_MONTH)));
	}

	/**
	 * 获取下一个code
	 *
	 * @param valueMapping 动态映射字符（传入以格式定义关键字为key的映射值）
	 * @return 转换后的code结果
	 */
	@Override
	public String getNextCode(Map<String, String> valueMapping) {
		//没有传入映射方式值的时候，默认使用基类的实现方式
		if (CollectionUtils.isEmpty(valueMapping)) {
			return super.getNextCode(null);
		}
		//判断固定生成的时间映射，是否为当前日期
		if (this.checkNowDate()) {
			/*
			 * 相同，映射年结果与现在时间不冲突，继续使用指定方式绑定
			 */
			String replaceStr = codeFactory;
			//遍历同步固定资源，并替换结果值
			for (Map.Entry<String, String> item :
					mapper.entrySet()) {
				replaceStr = StringUtils.replace(replaceStr, "[" + item.getKey() + "]", item.getValue());
			}
			//遍历非固定值的动态资源，并替换结果值
			for (Map.Entry<String, String> item :
					valueMapping.entrySet()) {
				//按默认方式替换
				replaceStr = StringUtils.replace(replaceStr, "{" + item.getKey() + "}", item.getValue());
			}
			//替换生成的id号
			replaceStr = StringUtils.replace(replaceStr, "[incrementId]", this.getNextIncrementId());
			return replaceStr;
		} else {
			/*
			 * 不相同，更新映射值，并初始化剩余资源，
			 */
			this.setDateMapping();
			this.init();
			//继续调用自身，重新转换
			return this.getNextCode(valueMapping);
		}

	}

	/**
	 * 初始化资源
	 *
	 * @return
	 */
	@Override
	public InvoiceApplyCode init() {
		/*
		 * 按固定字符和额外的字符（‘-2017-’）寻找最进新增的code，并获取自增id号
		 */
		//按-yyyy-方式寻找最后一次保存的id
		EntityWrapper<InvoiceApply> contractEntityWrapper = new EntityWrapper<>();
		contractEntityWrapper.setSqlSelect("id");
		contractEntityWrapper.orderBy("id desc");
		contractEntityWrapper.like("code", "%AP"
				+ mapper.get("yyyy")
				+ mapper.get("MM")
				+ mapper.get("dd")
				+ "%", SqlLike.CUSTOM);
		Long maxId = (Long) invoiceApplyService.selectObj(contractEntityWrapper);

		/*
		 * 未存在值默认使用1
		 * 存在值使用截取出的id号
		 */
		if (maxId == null) {
			codeId = new AtomicInteger(1);
		} else {
			InvoiceApply invoiceApply = invoiceApplyService.selectById(maxId);
			String code = invoiceApply.getCode();
			if (code.length() > 10) {
				String endStr = code.substring(10, invoiceApply.getCode().length());
				if (org.apache.commons.lang3.StringUtils.isNumeric(endStr)) {
					codeId = new AtomicInteger(Integer.valueOf(endStr));
				}
			}
		}
		return this;
	}
}
